﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Windows;
using System.Windows.Data;
using WPFCABShell.Shell.Interface;
using WPFCABShell.Shell.Interface.Services.Command;
using WPFCABShell.Shell.Interface.Services.Menu;
using Microsoft.Practices.CompositeUI.Commands;
using Microsoft.Practices.ObjectBuilder;
using SCSFContrib.CompositeUI.WPF.Workspaces;
using Shortcuts.Services;
using Kent.Boogaart.HelperTrinity;
using WPF = System.Windows.Input;

namespace Shortcuts
{
	public sealed class ShortcutsPresenter : Presenter<IShortcutsView>, INotifyPropertyChanged, IBuilderAware
	{
		private readonly ICommandService _commandService;
		private readonly IMenuService _menuService;
		private readonly IShortcutsService _shortcutsService;
		private ICommand _addShortcutGroupCommand;
		private ICommand _deleteShortcutGroupCommand;
		private ICommand _renameShortcutGroupCommand;
		private ICommand _addShortcutCommand;
		private ICommand _deleteShortcutCommand;
		private IMenuItem _deleteShortcutGroupMenuItem;
		private IMenuItem _renameShortcutGroupMenuItem;
		private IMenuItem _addShortcutMenuItem;
		private IMenuItem _deleteShortcutMenuItem;

		public ICommand AddShortcutGroupCommand
		{
			get
			{
				return _addShortcutGroupCommand;
			}
			private set
			{
				if (_addShortcutGroupCommand != value)
				{
					_addShortcutGroupCommand = value;
					OnPropertyChanged("AddShortcutGroupCommand");
				}
			}
		}

		public ICommand DeleteShortcutGroupCommand
		{
			get
			{
				return _deleteShortcutGroupCommand;
			}
			private set
			{
				if (_deleteShortcutGroupCommand != value)
				{
					_deleteShortcutGroupCommand = value;
					OnPropertyChanged("DeleteShortcutGroupCommand");
				}
			}
		}

		public ICommand RenameShortcutGroupCommand
		{
			get
			{
				return _renameShortcutGroupCommand;
			}
			private set
			{
				if (_renameShortcutGroupCommand != value)
				{
					_renameShortcutGroupCommand = value;
					OnPropertyChanged("RenameShortcutGroupCommand");
				}
			}
		}

		public ICommand AddShortcutCommand
		{
			get
			{
				return _addShortcutCommand;
			}
			private set
			{
				if (_addShortcutCommand != value)
				{
					_addShortcutCommand = value;
					OnPropertyChanged("AddShortcutCommand");
				}
			}
		}

		public ICommand DeleteShortcutCommand
		{
			get
			{
				return _deleteShortcutCommand;
			}
			private set
			{
				if (_deleteShortcutCommand != value)
				{
					_deleteShortcutCommand = value;
					OnPropertyChanged("DeleteShortcutCommand");
				}
			}
		}

		public ICollection<IShortcutGroup> ShortcutGroups
		{
			get
			{
				return _shortcutsService.Groups;
			}
		}

		public event PropertyChangedEventHandler PropertyChanged;

		public ShortcutsPresenter(
			[Dependency(NotPresentBehavior = NotPresentBehavior.Throw)] ICommandService commandService,
			[Dependency(NotPresentBehavior = NotPresentBehavior.Throw)] IMenuService menuService,
			[Dependency(NotPresentBehavior = NotPresentBehavior.Throw)] IShortcutsService shortcutsService)
		{
			_commandService = commandService;
			_menuService = menuService;
			_shortcutsService = shortcutsService;
		}

		protected override void OnViewSet()
		{
			base.OnViewSet();

			AddShortcutGroupCommand = _commandService.CreateCommand(WorkItem.Commands[Commands.AddShortcutGroup], "Add Group", null);
			DeleteShortcutGroupCommand = _commandService.CreateCommand(Commands.DeleteShortcutGroup, "Delete Group...", null);
			RenameShortcutGroupCommand = _commandService.CreateCommand(Commands.RenameShortcutGroup, "Rename Group...", null);
			AddShortcutCommand = _commandService.CreateCommand(Commands.AddShortcut, "Add Shortcut...", null);
			DeleteShortcutCommand = _commandService.CreateCommand(Commands.DeleteShortcut, "Delete Shortcut...", null);

			//register context menu
			WorkItem.RootWorkItem.UIExtensionSites.RegisterSite(ExtensionSites.ContextMenus.Shortcuts.Name, View.ContextMenu);
			//register context menu items
			_menuService.Add(ExtensionSites.ContextMenus.Shortcuts.Name, AddShortcutGroupCommand, ExtensionSites.ContextMenus.Shortcuts.AddGroup.GroupIndex, ExtensionSites.ContextMenus.Shortcuts.AddGroup.Index, null);
			_deleteShortcutGroupMenuItem = _menuService.Add(ExtensionSites.ContextMenus.Shortcuts.Name, DeleteShortcutGroupCommand, ExtensionSites.ContextMenus.Shortcuts.DeleteGroup.GroupIndex, ExtensionSites.ContextMenus.Shortcuts.DeleteGroup.Index, null);
			_renameShortcutGroupMenuItem = _menuService.Add(ExtensionSites.ContextMenus.Shortcuts.Name, RenameShortcutGroupCommand, ExtensionSites.ContextMenus.Shortcuts.RenameGroup.GroupIndex, ExtensionSites.ContextMenus.Shortcuts.RenameGroup.Index, null);

			_addShortcutMenuItem = _menuService.Add(ExtensionSites.ContextMenus.Shortcuts.Name, AddShortcutCommand, ExtensionSites.ContextMenus.Shortcuts.AddShortcut.GroupIndex, ExtensionSites.ContextMenus.Shortcuts.AddShortcut.Index, null);
			_deleteShortcutMenuItem = _menuService.Add(ExtensionSites.ContextMenus.Shortcuts.Name, DeleteShortcutCommand, ExtensionSites.ContextMenus.Shortcuts.DeleteShortcut.GroupIndex, ExtensionSites.ContextMenus.Shortcuts.DeleteShortcut.Index, null);
		}

		void IBuilderAware.OnBuiltUp(string id)
		{
		}

		void IBuilderAware.OnTearingDown()
		{
			WorkItem.RootWorkItem.UIExtensionSites.UnregisterSite(ExtensionSites.ContextMenus.Shortcuts.Name);
		}

		public void SelectShortcutGroupOrShortcut(object shortcutGroupOrShortcut)
		{
			_deleteShortcutGroupMenuItem.CommandParameter = shortcutGroupOrShortcut;
			_renameShortcutGroupMenuItem.CommandParameter = shortcutGroupOrShortcut;
			_addShortcutMenuItem.CommandParameter = shortcutGroupOrShortcut;
			_deleteShortcutMenuItem.CommandParameter = shortcutGroupOrShortcut;
		}

		[CommandHandler(Commands.AddShortcutGroup)]
		public void AddShortcutGroup(object sender, EventArgs e)
		{
			if (FinishGroupRename())
			{
				IShortcutGroup newGroup = _shortcutsService.AddGroup("Unnamed");
				RenameGroup(newGroup);
			}
		}

		public void RenameGroup(IShortcutGroup group)
		{
			View.GroupUnderEdit = group;
		}

		public bool FinishGroupRename()
		{
			if (View.GroupUnderEdit != null)
			{
				IShortcutGroup group = View.GroupUnderEdit;

				if ((group.Name == null) || (group.Name.Trim().Length == 0))
				{
					View.InvalidGroupName();
					return false;
				}

				View.GroupUnderEdit = null;
			}

			return true;
		}

		public void DeleteGroup(IShortcutGroup group)
		{
			if (View.ConfirmDelete(group))
			{
				_shortcutsService.Groups.Remove(group);
				View.GroupUnderEdit = null;
			}
		}

		public void AddShortcut(IShortcutGroup group)
		{
			ICommandsView commandsView = WorkItem.SmartParts.AddNew<CommandsView>();
			WindowSmartPartInfo smartPartInfo = new WindowSmartPartInfo("Commands");
			smartPartInfo.IsModal = true;
			smartPartInfo.StartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
			smartPartInfo.ShowInTaskbar = false;
			smartPartInfo.Owner = View.Window;
			WorkItem.Workspaces[Workspaces.WindowWorkspace].Show(commandsView, smartPartInfo);

			if (commandsView.IsAccepted)
			{
				foreach (ICommand command in commandsView.SelectedCommands)
				{
					group.AddShortCut(command);
				}
			}
		}

		public void DeleteShortcut(IShortcut shortcut)
		{
			if (View.ConfirmDelete(shortcut))
			{
				shortcut.Group.Shortcuts.Remove(shortcut);
			}
		}

		private void OnPropertyChanged(string propertyName)
		{
			EventHelper.Raise(PropertyChanged, this, new PropertyChangedEventArgs(propertyName));
		}

		public sealed class UnderEditConverter : IMultiValueConverter
		{
			public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
			{
				IShortcutGroup currentGroup = values[0] as IShortcutGroup;
				IShortcutGroup groupUnderEdit = values[1] as IShortcutGroup;
				bool match = object.ReferenceEquals(currentGroup, groupUnderEdit);

				switch (parameter as string)
				{
					case "TextBlock":
						return match ? Visibility.Collapsed : Visibility.Visible;
					case "TextBox":
						return match ? Visibility.Visible : Visibility.Collapsed;
				}

				return DependencyProperty.UnsetValue;
			}

			public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
			{
				throw new NotImplementedException();
			}
		}
	}
}
